/*
*    Author : heiden deng(dengjianquan@beyondcent.com)
*    2017/07/19
*    version 0.0.9
*    黑白名单处理类声明
*/
#pragma once
#ifndef HTSC_CONDITIONROUTER_H
#define HTSC_CONDITIONROUTER_H

#include "htsc_router.h"
#include "htsc_grpc_consumer_utils.h"
#include <grpc/support/log.h>
#include <set>
#include <string>
#include <map>

#ifdef __cplusplus
extern "C" {
#endif

using namespace std;
class ConditionRouter :
	public Router
{
	class MatchPair {
	public:
		set<string> matches;
		set<string> mismatches;
	public:
		bool isMatch(string value, url_t* param) {
			int mathcesNum = matches.size();
			int mismatchesNum = mismatches.size();

			if (mathcesNum > 0 && mismatchesNum > 0) {
				gpr_log(GPR_ERROR,"路由规则配置出错，条件不能同时出现=和!=，请检查！");
				return false;
			}
			if (mathcesNum == 0 && mismatchesNum == 0) {
				gpr_log(GPR_ERROR, "ConditionRouter.MatchPair.isMatch程序发现一个不应该出现的情况");
				return false;
			}

			bool defaultValue;
			if (mathcesNum > 0) {
				defaultValue = false;// matches，如果都匹配不上返回false
			}
			else {
				defaultValue = true;// mismatches，如果都匹配不上返回true
			}

			for (std::set<std::string>::iterator it = matches.begin();it != matches.end();it++) {
				if (is_match_glob_pattern(*it, value, param)) {
					return true;
				}
			}

			for (std::set<std::string>::iterator it = mismatches.begin();it != mismatches.end();it++) {
				if (is_match_glob_pattern(*it, value, param)) {
					return false;
				}
			}

			return defaultValue;
		}
	};
	url_t *url;
	int priority;
	bool force;
	std::map<std::string, MatchPair> whenCondition;
	std::map<std::string, MatchPair> thenCondition;
private:
	bool matchWhen(url_t* url);
	bool matchThen(url_t* url, url_t* param);
	bool matchCondition(std::map<std::string, MatchPair> condition, url_t* url, url_t* param);
public:
	ConditionRouter(url_t* url_param);
	static std::map<std::string, MatchPair> parseRule(std::string rule);
	int route(std::vector<provider_t*> &providers, url_t *url_param);
	int get_priority() { return priority; }
	~ConditionRouter();
};


#ifdef __cplusplus
}
#endif

#endif // !HTSC_CONDITIONROUTER_H


